package com.leboncoin.batch;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import org.junit.After;

import com.leboncoin.bean.ClassifiedBean;
import com.leboncoin.bean.SearchItemBean;
import com.leboncoin.bean.SubscriptionBean;
import com.leboncoin.html.LeboncoinHtmlClassifiedDetail;
import com.leboncoin.html.LeboncoinHtmlSearchResult;
import com.leboncoin.util.FormatManager;
import com.thoughtworks.selenium.Selenium;
import com.thoughtworks.selenium.SeleniumException;
import java.util.logging.Level;

/**
 * Base class for leboncoin search
 * @author ben
 */
public class CommonSearch {
	
	protected static Logger logger = Logger.getLogger(CommonSearch.class.getName());	
	protected static CommonSearch instance;
	
	protected Selenium selenium;
	
	private CommonSearch(Selenium selenium){
		this.selenium = selenium;
	}
	
	public static CommonSearch getInstance(Selenium selenium){
		if (instance == null){
			instance = new CommonSearch(selenium);
		}
		return instance;
	}
	
    /**
     * Search classified from subscriptionBean
     * @param daySearch
     * @param subscriptionBean
     * @throws Exception 
     */
	public void searchFromSubscription(Boolean daySearch, SubscriptionBean subscriptionBean) throws Exception {
		
		logger.log(Level.INFO, "Abonnement: {0}", subscriptionBean.getName());

		for (SearchItemBean searchItemBean:subscriptionBean.getSearchItems()){
			
			List<ClassifiedBean> classifieds = new ArrayList<ClassifiedBean>();
		
			logger.log(Level.INFO, "Category:{0}", searchItemBean.getSearchCategory());
			logger.log(Level.INFO, "Text:{0}", searchItemBean.getSearchText());
			
			if (searchItemBean.getSearchLocation() != null 
					&& searchItemBean.getSearchLocation().equals(SearchItemBean.LocationType.LISTE_CP)){
				for (String zipCode:searchItemBean.getZipCodes()){
					selenium.open("/annonces/offres/auvergne/puy_de_dome/");			
					selenium.waitForPageToLoad("10000");
					if (searchItemBean.getSearchCategory()!=null){
						selenium.select("id=search_category", "label="+searchItemBean.getSearchCategory());
					}
					selenium.type("id=zipcoded", zipCode);
					List<ClassifiedBean> classifiedsTmp = searchFromSearchItem(searchItemBean, daySearch);
					classifieds.addAll(classifiedsTmp);
				}
			} else {
				selenium.open("/annonces/offres/auvergne/puy_de_dome/");		
				if (searchItemBean.getSearchCategory()!=null){
					selenium.select("id=search_category", "label="+searchItemBean.getSearchCategory());
				}
				if (searchItemBean.getSearchLocation() != null) {
					selenium.select("id=searcharea", "label="+searchItemBean.getSearchLocation().toString());
				}
				classifieds = searchFromSearchItem(searchItemBean, daySearch);
			}
			searchItemBean.setSearchResults(classifieds);				
		}
	}

    /**
     * Search classifieds from given searchItemBean
     * @param searchItemBean
     * @param daySearch
     * @return 
     */
	protected List<ClassifiedBean> searchFromSearchItem(SearchItemBean searchItemBean, Boolean daySearch){
		
		List<ClassifiedBean> classifieds = null;
		selenium.type("id=searchtext", searchItemBean.getSearchText());
        
        String idPriceMin = "ps";
        String idPriceMax = "pe";
        if (searchItemBean.getSearchCategory().equalsIgnoreCase("locations")) {
            idPriceMin = "mrs";
            idPriceMax = "mre";
        }
        
		if (searchItemBean.getPriceMin()!=null){
			String prixMin = FormatManager.formatNumber(searchItemBean.getPriceMin());
			selenium.select("id="+idPriceMin, "label="+prixMin);
		}
		if (searchItemBean.getPriceMax()!=null){
			String prixMax = FormatManager.formatNumber(searchItemBean.getPriceMax());
			if (prixMax != null){
				selenium.select("id="+idPriceMax, "label="+prixMax);
			}
		}
		try {Thread.sleep(3000);} catch (InterruptedException e){logger.warning("interrupted!");}
		
		// Autres options a cocher
		if (searchItemBean.getCheckBoxList().size() > 0){
			for (String checkBoxId:searchItemBean.getCheckBoxList()){
				selenium.click("id="+checkBoxId);
			}
		}
		
		// Dans le titre seulement
		selenium.click("id=ctitle");
		
		
		selenium.click("id=searchbutton");
		selenium.waitForPageToLoad("60000");

		String htmlSource = selenium.getHtmlSource();

		LeboncoinHtmlSearchResult htmlPage = new LeboncoinHtmlSearchResult(htmlSource);
		classifieds = htmlPage.getClassifiedList(daySearch);
		
		for(ClassifiedBean classifiedBean:classifieds){
			
			// Link classified to search item
			classifiedBean.setSearchItemBean(searchItemBean);
			
			// Get detail page to populate price and images
			String htmlDetailSource = null;
			try {
				selenium.open(classifiedBean.getLink());
				selenium.waitForPageToLoad("20000");
				try {
					selenium.click("//img[contains(@src,'thumbs')]");
				} catch (SeleniumException e){
					logger.log(Level.SEVERE, "Impossible to get image thumbs and price from classified {0}", classifiedBean.getLink());
				}
				htmlDetailSource = selenium.getHtmlSource();
			} catch (SeleniumException e){
				logger.severe(e.getMessage());
			}
			if (htmlDetailSource != null){
				try{
					LeboncoinHtmlClassifiedDetail htmlDetailPage = new LeboncoinHtmlClassifiedDetail(htmlDetailSource);
					htmlDetailPage.populatePrice(classifiedBean);
					htmlDetailPage.populateImages(classifiedBean);
				}catch (Exception e){
					logger.severe("Impossible to populate image and price from source ");
					System.err.print(htmlDetailSource);
					System.err.print(e);
				}
			}

		}
		
		return classifieds;
	}
	
	@After
	public void tearDown() throws Exception {
		selenium.stop();
	}


}
